package com.cn.sl.server.api.system.department.service.impl

import com.cn.sl.server.api.system.department.dao.rdb.DepartmentDao
import com.cn.sl.server.api.system.department.model.dto.AddDepartmentDto
import com.cn.sl.server.api.system.department.model.dto.DepartmentDto
import com.cn.sl.server.api.system.department.model.dto.EditDepartmentDto
import com.cn.sl.server.api.system.department.service.DepartmentService
import com.cn.sl.server.api.system.department.util.updateChildrenNamePath
import com.cn.sl.server.common.annotation.transaction.Commit
import com.cn.sl.server.common.annotation.transaction.ReadOnly
import com.cn.sl.server.util.findDeepChildren
import org.springframework.stereotype.Service

@Service
class DepartmentServiceImpl(
    val departmentDao: DepartmentDao
) : DepartmentService {

    @ReadOnly
    override fun findAll(): List<DepartmentDto> {
        return departmentDao.findAll().map { DepartmentDto(it) }
    }

    @Commit
    override fun add(dto: AddDepartmentDto) {
        val parentEntity = dto.parentId?.let { departmentDao.findById(it) }
        val entity = dto.toEntity(parentEntity)
        departmentDao.save(entity)
    }

    @Commit
    override fun edit(dto: EditDepartmentDto) {
        departmentDao.findById(dto.id).let {
            val parentEntity = dto.parentId?.let { departmentDao.findById(it) }
            val entity = dto.merge(it, parentEntity)
            departmentDao.save(entity)

            val entities = departmentDao.findAll()

            updateChildrenNamePath(entity, entities)

            departmentDao.saveAll(entities)
        }
    }

    @ReadOnly
    override fun findById(id: Long): DepartmentDto {
        return DepartmentDto(departmentDao.findById(id))
    }

    @Commit
    override fun delete(id: Long) {
        departmentDao.findById(id).let {
            departmentDao.delete(it)

            val entities = departmentDao.findAll()
            val children = findDeepChildren(it, entities, { it.id }, { it.parentId })
            departmentDao.deleteAll(children)
        }
    }
}